#pragma once

#include "Socket.h"
#include <stdint.h>
#include <functional>
#include <memory>
#include <mutex>
#include <atomic>

class Epoll;
class EventLoop;
class Channel
{
private:
    int m_fd = -1;
    EventLoop* m_loop;
    std::atomic<bool> m_in_epoll{false};
    uint32_t m_events = 0;
    uint32_t m_revents = 0;

    std::function<void()> m_read_callback;
    std::function<void()> m_close_callback;
    std::function<void()> m_error_callback;
    std::function<void()> m_write_callback;

public:
    Channel(EventLoop* loop, int fd);
    ~Channel();

    int fd();
    bool in_epoll();
    uint32_t events();
    uint32_t revents();

    void use_et();
    
    void enable_reading();
    void disable_reading();
    void enable_writing();
    void disable_writing();

    void disable_all();
    void remove();

    void set_inepoll();
    void set_not_inepoll();

    void set_revents(uint32_t ev);

    void handle_event();

    void set_read_callback(std::function<void()> fn);
    void set_close_callback(std::function<void()> fn);
    void set_error_callback(std::function<void()> fn);
    void set_write_callback(std::function<void()> fn);
};
